#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <cstdio>
#include "RingQueue.hpp"
#include "Task.hpp"

void *ProDu(void * arvgs)
{
    RingQueue<Task>* RQ = static_cast<RingQueue<Task>*>(arvgs);

    //拿到队列了，可以开始生产数据了
    while(1)
    {
       int x = rand()%10 + 1;
       int y = rand()%5 + 1;
       int op = rand()%5;
       
       Task task(x,y,oper[op],mymath);
       RQ->push(task);

       std::cout << task.toTaskString() << std::endl;
    }
}

void *ConSu(void * arvgs)
{
    RingQueue<Task>* RQ = static_cast<RingQueue<Task>*>(arvgs);
    
    while(1)
    {
        sleep(1);
        Task data;
        RQ->pop(&data);  // 利用的是operation赋值重载
        
        std::cout << data() << std::endl;
    }

}


int main()
{
    srand((unsigned int)time(nullptr) ^ getpid() ^ pthread_self());


    // 直接来10个生产者，5个消费者     
    pthread_t producer[10],consumer[5];

    RingQueue<Task> RQ(10);

    // 多线程模式中，生产者和生产者，消费者和消费者之间是要形成互斥关系的 ， 要维持这个关系就需要用到两把锁

    // 我们要知道 *(producer + i) = producer[i] -> producer+i = &producer[i];
    for(int i = 0 ;  i < 10 ; i++)
    pthread_create(producer+i,nullptr,ProDu,&RQ);

    for(int i = 0 ;  i < 5  ; i++)
    pthread_create(consumer+i,nullptr,ConSu,&RQ);

    while(1);


    // 我们要知道 *(producer + i) = producer[i] -> producer+i = &producer[i];
    for(int i = 0 ;  i < 10 ; i++)
    pthread_join(producer[i],nullptr);
    for(int i = 0 ;  i < 5 ; i++)
    pthread_join(consumer[i],nullptr);
    
    return 0;
}